/* Abstract Machine Code 
 * Will be generated from 3addr code (Imm.h and Imm.C)
*/ 
#ifndef __AMC_H__
#define __AMC_H__

#include "Imm.h"
#include "Ast.h"

#define MAX_REG	1000
// Dedicated registers 
#define SP		" R009 "			/* stack pointer */
#define LR		" R008 "			/* link register */
#define BP		" R007 "			/* base pointer */
#define SL		" R006 "			/* shift loop register */
#define GR0		" R010 "			/* general 0~6 */
#define GR1		" R011 "
#define GR2		" R012 "
#define GR3		" R013 "
#define GR4		" R014 "
#define GR5		" R015 "
#define GR6		" R016 "
#define GF0		" F000 "			/* general float */
#define GF1		" F001 "

class FunctionEntry;

string newRegister(bool isFloat=false);
enum Op {
	EXPR,			/* x = y op z */
	IF,			/* if x gotoL or ifFalse x goto */
	IF_REL,		/* if x relop y goto L */
	GOTO,			/* unconditional jump */
	PARAM,
	CALL,
	ENTER,			/* beginning of function */
	LEAVE,			/* return value + leave */
	LABEL,			/* special purpose : LABEL */
	INLINE,
};

class AbsMachCode {
	public:
		AbsMachCode() {}
		static void generate(ImmCodes *icode, ostream &os);
		static bool immToMac(ImmCode *ic, ostream& os);
	protected:
		static string _convertInt2Float(ExprNode* from, ostream &os);
		static string _convertFloat2Int(ExprNode* from, ostream &os);
		static void _saveRegisters(FunctionEntry* fe,ostream &os);
		static void _restoreRegisters(FunctionEntry* fe,ostream &os);
	protected:
};

#endif
